home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / forth-to-latex-pretty-print / F2L / C source / Forth2LaTeX.c next >
Encoding:
C/C++ Source or Header  |  1995-01-05  |  25.4 KB  |  979 lines  |  [TEXT/KAHL]

  1. /*
  2.  
  3.         Forth2LaTeX  --  A Forth code pretty-printer for LaTeX
  4.         
  5.         
  6.         
  7.         (c) 1994, Ronald T. Kneusel, all rights reserved.
  8.         
  9.         Internet: kneusel@studsys.mscs.mu.edu
  10.         
  11.         
  12.   See the Forth2LaTeX manual for information about using this program.
  13.   This code is compatible with Unix, VMS, MS-DOS, and Macintosh computers.
  14.   
  15.   This code maybe distributed freely as long as all notices remain intact.
  16.   For profit distribution allowed only with the written consent of the 
  17.   author.
  18.   
  19.   Please pardon this messy and _very_ direct port from the Modula-2 original!
  20.   
  21.   
  22.   Last Mod:  01/05/95
  23.   
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #define TRUE  1
  32. #define FALSE 0
  33.  
  34. #define last 32766         /* for use in string functions */
  35.  
  36. #define MAX  256           /* longest string */
  37.  
  38. /************************************************************************
  39.  
  40.      This code runs on Macintosh, MS-DOS, Unix, and VMS.  Simply define
  41.      the appropriate system below:
  42.      
  43. *************************************************************************/
  44.  
  45. #define MACINTOSH    /* choose one: MACINTOSH, VAX, UNIX, or MSDOS */
  46.  
  47. #ifdef MACINTOSH
  48. #include <console.h>
  49. #endif
  50.  
  51. /* Globals */
  52.  
  53. FILE  *f, *g, *w, *t;           /* file pointers */
  54.  
  55. int DONE,TOC,UP,INDEX,BOLD;     /* switches */
  56. int RA,QUOTE,SECTIONS;
  57. int COMMENTS,FIRST;
  58. int NOBRACKET;
  59.  
  60. struct tree         /* binary tree for defined word list */
  61. {
  62.     long int  line;          /* line number of definition */
  63.     char name[MAX];          /* name of defined word      */
  64.     struct tree *left;       /* left and right subtrees   */
  65.     struct tree *right;
  66. } ;
  67.  
  68. struct tree *root;              /* root of the tree */
  69.  
  70. char  infile[MAX], outfile[MAX];     /* source and dest file names */
  71.  
  72. /* if your compiler needs prototypes, include this file: */
  73.  
  74. #include "proto.c"
  75.  
  76.  
  77. /************************************************************************/
  78.  
  79.  
  80. main(int argc, char *argv[])
  81.  
  82. #ifdef MACINTOSH
  83.   argc = ccommand(&argv);
  84. #endif
  85.  
  86.   Header();
  87.   Init();
  88.  
  89.   root = NULL;
  90.  
  91.   switch(argc){
  92.     case 1: helpScreen(); 
  93.             break;
  94.     case 2: ShowSwitches();
  95.             ConvertFile(argv[1]); 
  96.             break;
  97.     default: setSwitches(argv[2]);
  98.              ShowSwitches();
  99.              ConvertFile(argv[1]);
  100.   }
  101.   
  102. #ifndef VAX 
  103.   return 0;
  104. #endif
  105. }
  106.  
  107. /*************************************************************************
  108.  
  109.      Functions - these are for the most part direct translations of the
  110.                  original Modula-2 functions, including the names
  111.                  
  112. *************************************************************************/
  113.  
  114. void helpScreen(void)
  115. {
  116.     printf("Quick help:\n\n");
  117.     printf("Command line:  Forth2LaTeX <infile> [<switch settings>]\n\n");
  118.     printf("Switches:  -xxx where presence of character 'x' is on\n\n");
  119.     printf("  u  -- uppercase code\n");
  120.     printf("  l  -- comments LATEX (default is FORTH)\n");
  121.     printf("  t  -- generate table of contents\n");
  122.     printf("  i  -- index of defined words\n");
  123.     printf("  b  -- bold colon definition names\n");
  124.     printf("  r  -- style is REPORT (default is ARTICLE)\n");
  125.     printf("\nExample: -ibr is INDEX, BOLD, and REPORT on, others off or ");
  126.     printf("default\n\n");
  127.     printf("See the manual for more information.\n\n");
  128.     printf("Author contact: kneusel@studsys.mscs.mu.edu\n\n");
  129. }
  130.  
  131. void Init(void)
  132. /* default settings */
  133. {
  134.    UP = FALSE;  COMMENTS = FALSE;  TOC = FALSE;
  135.    INDEX = FALSE; BOLD = FALSE;  RA = FALSE;
  136. }
  137.  
  138. void setSwitches(char *s)
  139. /* set the command line switches */
  140. {
  141.   int i;
  142.   
  143.   for(i=1;i<strlen(s);i++)
  144.     switch(up1(s[i])){
  145.        case 'U': UP       = TRUE;  break;
  146.        case 'L': COMMENTS = TRUE;  break;
  147.        case 'T': TOC      = TRUE;  break;
  148.        case 'I': INDEX    = TRUE;  break;
  149.        case 'B': BOLD     = TRUE;  break;
  150.        case 'R': RA       = TRUE;  break;
  151.        default : break; /* ignore */
  152.      }     
  153. }
  154.  
  155. void ShowSwitches(void)
  156. /* show the current switch settings */
  157. {
  158.   printf("Switches on: ");
  159.   if (UP) printf("UPPERCASE  ");
  160.   if (COMMENTS) printf("LATEX  ");
  161.   if (TOC) printf("TABLE-OF-CONTENTS  ");
  162.   if (INDEX) printf("INDEX  ");
  163.   if (BOLD) printf("BOLD  ");
  164.   if (RA) printf("REPORT"); 
  165.   printf("\n\n");  
  166. }
  167.  
  168. /*********************************************
  169.  *                                           *
  170.  *  C versions of Modula-2 string functions  *
  171.  *                                           *
  172.  *********************************************/
  173.  
  174. int Len(char *s)
  175. {  /* length of the string s */
  176.   return strlen(s);
  177. }
  178.  
  179. void Append(char *s1, char *s2)
  180. /* append s2 to s1 */
  181. {
  182.    s1 = strcat(s1,s2);
  183. }
  184.  
  185. void AppendCh(char *s, int c)
  186. /* append character c to s */
  187. {  
  188.    char nullstr[2];
  189.    
  190.    nullstr[1] = '\0';
  191.    nullstr[0] = c;
  192.    s = strcat(s,nullstr);
  193. }
  194.  
  195. int Equal(char *s1, char *s2)
  196. /* true if s1 == s2 */
  197. {
  198.   return ( strcmp(s1,s2) == 0 ) ? TRUE : FALSE; 
  199. }
  200.  
  201. void Copy(char *d, char *s, int st, int len)
  202. /* copy len chars from s into d starting at position st of s */
  203. {
  204.   if (st+len <= strlen(s)) {
  205.     strncpy(d,s+st,len);
  206.     d[len] = '\0'; 
  207.   } else {
  208.     strncpy(d,s+st,strlen(s)-st);
  209.     d[strlen(s)-st]='\0';
  210.   }
  211. }
  212.  
  213. int Same(char *s, int st, int len, char *t)
  214. /* is t the same as s from st length len? */
  215. {
  216.   if (st <= strlen(s))
  217.     return (strncmp(t,s+st,len) == 0) ? TRUE : FALSE;
  218. }
  219.  
  220. int Occurs(char *s, int st, char *t)
  221. /* does t occur in s starting at or after st? return index */
  222. {
  223.   int i;
  224.   
  225.   for(i=st; i<strlen(s); i++)
  226.   {
  227.     if (strncmp(s+i,t,strlen(t))==0)
  228.       return i;
  229.   }
  230.   return last;   /* no string will be larger than this */
  231. }
  232.  
  233. void Del(char *s,int st, int len)
  234. /* delete the len characters from s starting at st */
  235. {
  236.   int i,j,n;
  237.   
  238.   n = strlen(s);
  239.   if (st+len-1 >= n)  len = n - st;   /* keep in range */
  240.   
  241.   for(i=st, j=st+len; j<=n; i++, j++)
  242.     s[i] = s[j];
  243. }
  244.  
  245. /************************************************************/
  246.  
  247. void WriteTheString(FILE *f, char *s)     
  248. /* write a string to disk */
  249. {
  250.   fprintf(f,"%s\n",s);
  251. }
  252.  
  253. int ReadTheString(FILE *f, char *s)       
  254. /* read a string from disk */
  255. { int c,i;
  256.   i=0;
  257.   c=fgetc(f);
  258.   while ((c!=EOF) && (c!='\n')) {
  259.     s[i] = c;
  260.     i++;
  261.     c = fgetc(f);
  262.   }
  263.   s[i]='\0';
  264.   return (c == EOF) ? TRUE : FALSE;
  265. }
  266.  
  267. int up1(int c)
  268. /* make c uppercase */
  269. {  
  270.    return (c >= 'a' && c <= 'z') ? c+'A'-'a' : c;
  271. }
  272.  
  273. void Upper(char *s)       
  274. /* make s uppercase, ignores " " and \ ... */
  275. {
  276.   int i, quoted;
  277.   
  278.   quoted = FALSE;  i = 0;
  279.   while (i <= strlen(s))
  280.   {
  281.     if (s[i] == '\\') {
  282.       i = strlen(s)+10;
  283.     }
  284.     if (quoted == FALSE) {
  285.       s[i] = up1(s[i]);
  286.     }
  287.     if (s[i] == '"') {
  288.       quoted = (quoted == TRUE) ? FALSE : TRUE;
  289.     }
  290.     ++i;
  291.   }
  292. }
  293.  
  294. void Upper0(char *s)    
  295. /* make s uppercase, ignores nothing */
  296. {
  297.   int i;  
  298.   for(i=0;i<strlen(s);i++)
  299.     s[i] = up1(s[i]);
  300. }
  301.  
  302. void Dispose(struct tree *p)  
  303. /* Pascal "Dispose" */
  304. {
  305.   free(p);
  306. }
  307.  
  308. void Insert(struct tree *f, struct tree **r)
  309. /* insert a tree node */
  310. {
  311.   if (*r==NULL)
  312.     *r = f; 
  313.   else {
  314.     if (strcmp(f->name, (*r)->name) < 0 )
  315.       Insert(f, &(*r)->left);
  316.     else
  317.       Insert(f,&(*r)->right);
  318.   }
  319. }
  320.  
  321. void strclr(char *s)
  322. /* set the string s to the empty string */
  323. {
  324.   s[0] = '\0';
  325. }
  326.  
  327. void addName(char *s, long int line)
  328. /* add a name and line number to the tree */
  329. {
  330.   struct tree *p;
  331.   
  332.   if (root == NULL) {
  333.     root = (struct tree *) malloc(sizeof(struct tree));
  334.     if (root != NULL) {
  335.       strcpy(root->name,s);
  336.       root->line = line;
  337.       root->left = NULL;
  338.       root->right= NULL;
  339.     } else {
  340.       printf("Sorry, but there is not enough memory available.\n\n");
  341.       exit(1);
  342.     }
  343.   } else {
  344.     p = (struct tree *) malloc(sizeof(struct tree));
  345.     if (p != NULL) {
  346.       strcpy(p->name,s);
  347.       p->line = line;
  348.       p->left = NULL;
  349.       p->right= NULL;
  350.     } else {
  351.       printf("Sorry, but there is not enough memory available.\n\n");
  352.       exit(1);
  353.     }
  354.     Insert(p,&root);
  355.   }
  356. }
  357.  
  358. void StripSuffix(char *s, char *w)
  359. /* strips the file suffix if present */
  360. {
  361.   int i;
  362.   char t[MAX];
  363.   
  364.   strcpy(t,s);
  365.   Upper(t);
  366.   i = Occurs(t,0,".4TH");
  367.   if (i != last)
  368.     Copy(w,s,0,i);
  369.   else {
  370.     i = Occurs(t,0,".FORTH");
  371.     if (i != last)
  372.       Copy(w,s,0,i);
  373.     else {
  374.       i = Occurs(t,0,".FTH");
  375.       if (i != last) 
  376.         Copy(w,s,0,i);
  377.       else
  378.         strcpy(w,s);
  379.     }
  380.   }
  381. }
  382.  
  383. void Header(void)
  384. /* startup header */
  385. {
  386.   printf("\n\n");
  387.   printf("** Forth2LaTeX 1.9c **    ");
  388.   printf("Ronald T. Kneusel, 1994.  This program is freeware\n");
  389.   printf("--------------------------");
  390.   printf("--------------------------------------------------\n\n");
  391. }
  392.  
  393. void GetProgramInfo(void)
  394. /* get the title page info */
  395. {
  396.   int done,ok,n;
  397.   char str[MAX],prog[MAX],auth[MAX],start[MAX],
  398.        modif[MAX],modby[MAX],sum[MAX],t[MAX];
  399.   long int c;
  400.   
  401.   done = FALSE;
  402.   strclr(str); strclr(prog); strclr(auth); strclr(start);
  403.   strclr(modif); strclr(modby); strclr(sum); strclr(t);
  404.   c = 1;
  405.   done = ReadTheString(f,str);
  406.   while (!done)
  407.    {
  408.      if ((n=Occurs(str,0,"\\ Program:")) != last) {
  409.        Del(str,0,n+10); strcpy(prog,str); }
  410.      else if ((n=Occurs(str,0,"\\ Author:")) != last) {
  411.        Del(str,0,n+9);  strcpy(auth,str); }
  412.      else if ((n=Occurs(str,0,"\\ Started:")) != last) {
  413.        Del(str,0,n+10);  strcpy(start,str); }
  414.      else if ((n=Occurs(str,0,"\\ Modified:")) != last) {
  415.        Del(str,0,n+11);  strcpy(modif,str); }
  416.      else if ((n=Occurs(str,0,"\\ Modify By:")) != last) {
  417.        Del(str,0,n+12);  strcpy(modby,str); }
  418.      else if ((n=Occurs(str,0,"\\ Summary:")) != last) {
  419.        Del(str,0,n+10);  strcpy(sum,str); }
  420.      else if (Occurs(str,0,"\\ Comments:") != last) 
  421.        if (Occurs(str,0,"LATEX") != last)
  422.          COMMENTS = TRUE;
  423.        else if (Occurs(str,0,"FORTH") != last)
  424.          COMMENTS = FALSE;
  425.      else if (Occurs(str,0,"\\ Uppercase:") != last) 
  426.        if (Occurs(str,0,"ON") != last)
  427.          UP = TRUE;
  428.        else if (Occurs(str,0,"OFF") != last)
  429.          UP = FALSE;
  430.      else if (Occurs(str,0,"\\ Table of Contents:") != last) 
  431.        if (Occurs(str,0,"ON") != last)
  432.          TOC = TRUE;
  433.        else if (Occurs(str,0,"OFF") != last)
  434.          TOC = FALSE;
  435.      else if (Occurs(str,0,"\\ Index:") != last) 
  436.        if (Occurs(str,0,"ON") != last)
  437.          INDEX = TRUE;
  438.        else if (Occurs(str,0,"OFF") != last)
  439.          INDEX = FALSE;
  440.      else if (Occurs(str,0,"\\ Bold:") != last) 
  441.        if (Occurs(str,0,"ON") != last)
  442.          BOLD = TRUE;
  443.        else if (Occurs(str,0,"OFF") != last)
  444.          BOLD = FALSE;
  445.      else if (Occurs(str,0,"\\ Style:") != last) 
  446.        if (Occurs(str,0,"ON") != last)
  447.          RA = TRUE;
  448.        else if (Occurs(str,0,"OFF") != last)
  449.          RA = FALSE;
  450.      done = ReadTheString(f,str);
  451.      if ((Occurs(str,0,"ection:")==last) || (Occurs(str,0,"hapter:")==last))
  452.        ++c;
  453.    } /* while */
  454.    strcpy(str,"\\title{{\\bf ");  Append(str,prog);  Append(str,"}}");
  455.    WriteTheString(g,str);
  456.    strcpy(str,"\\author{{\\small "); Append(str,auth); Append(str,"}}");
  457.    WriteTheString(g,str);
  458.    WriteTheString(g,"\\date{{\\small \\today}}");
  459.    WriteTheString(g,"\\maketitle");
  460.    strcpy(str,"\\vspace{4in} \\hfil \\break {\\large{\\bf Program Information:}}");
  461.    Append(str," \\hfil \\break");
  462.    WriteTheString(g,str);
  463.    WriteTheString(g,"\\hfil \\break");
  464.    strcpy(str,"{\\bf Summary:}\\ \\ "); Append(str,sum);  Append(str,"\\hfil \\break");
  465.    WriteTheString(g,str);
  466.    strcpy(str,"{\\bf Author:}\\ \\ "); Append(str,auth); Append(str,"\\hfil \\break");
  467.    WriteTheString(g,str);
  468.    strcpy(str,"{\\bf Modified:}\\ \\ "); Append(str,modif); Append(str,"\\hfil \\break");
  469.    WriteTheString(g,str);
  470.    strcpy(str,"{\\bf Modify By:}\\ \\ "); Append(str,modby); Append(str,"\\hfil \\break");
  471.    WriteTheString(g,str);
  472.    sprintf(t,"%ld",c-1);
  473.    strcpy(str,"{\\bf Lines:}\\ \\ "); Append(str,t); Append(str,"\\hfil \\break \\clearpage");
  474.    WriteTheString(g,str);
  475. }  /* GetProgramInfo */
  476.  
  477. void CopyHeader(void)
  478. /* setup the document */
  479. {
  480.   char s[MAX];
  481.   
  482.   strcpy(s,"\\documentstyle[12pt]{");
  483.   if (RA)
  484.     Append(s,"report");
  485.   else
  486.     Append(s,"article");
  487.   Append(s,"}");
  488.   WriteTheString(g,s);
  489.   WriteTheString(g,"\\voffset=-0.8in");
  490.   WriteTheString(g,"\\hoffset=-0.5in");
  491.   WriteTheString(g,"\\textheight=9in");
  492.   WriteTheString(g,"\\textwidth=6.5in");
  493.   WriteTheString(g,"\\parindent=0pt");
  494.   WriteTheString(g,"\\begin{document}");
  495.   WriteTheString(g,"\\pagestyle{plain}");
  496.   WriteTheString(g,"\\pagenumbering{roman}");
  497. }
  498.  
  499. void HandleComment(int *i, char *str, char *out)
  500. /* process the comment portion of a line */
  501. {
  502.   int latex, q;
  503.   
  504.   Del(str,0,*i);    /* remove leading characters */
  505.   if (str[2]=='.') {  /* a \ . comment */
  506.     Del(str,0,3);
  507.     strcpy(out,str);
  508.     NOBRACKET = TRUE;
  509.   } else {
  510.     Append(out,"}{\\it");  latex = FALSE;
  511.     if (!COMMENTS) {
  512.       for(q=0;q<strlen(str);q++)
  513.        {
  514.          if (!latex) {
  515.            switch(str[q]){
  516.              case ' '  : Append(out,"\\ "); break;  /* convert special LaTeX */
  517.              case '_'  : Append(out,"\\_"); break;  /* characters            */
  518.              case '\11': Append(out,"\\ \\ \\ \\ "); break;
  519.              case '\\' : Append(out,"$\\backslash$"); break;
  520.              case '#'  : Append(out,"\\#"); break;
  521.              case '&'  : Append(out,"\\&"); break;
  522.              case '$'  : Append(out,"\\$"); break;
  523.              case '%'  : Append(out,"\\%"); break;
  524.              case '}'  : Append(out,"\\}"); break;
  525.              case '{'  : Append(out,"\\{"); break;
  526.              case '<'  : Append(out,"$<$"); break;
  527.              case '>'  : Append(out,"$>$"); break;
  528.              case '^'  : Append(out,"$\\uparrow$"); break;
  529.              case '`'  : latex = !latex;  break; /* LaTeX escape character */
  530.              case '~'  : Append(out,"$\\tilde{ }$"); break;
  531.            default:
  532.              AppendCh(out,str[q]);
  533.            }
  534.          } else {
  535.            if (str[q] != '`')
  536.              AppendCh(out,str[q]);
  537.            else
  538.              latex = !latex;
  539.          }
  540.        }
  541.       } else {
  542.         Append(out,str);
  543.       }
  544.     }
  545.     *i = last;  /* force loop to quit */
  546.  } /* HandleComment */
  547.  
  548. void HandleFunction(int *i, char *str, char *out, long int *c)
  549. /* process a colon definition */
  550. {
  551.    int q,old,s,k;
  552.    char name[MAX], t[MAX], w[MAX];
  553.  
  554.    if (((((*i>0) && (str[*i-1]==' ')) && (str[*i+1]==' ')) ||
  555.       ((*i==0) && (str[1]==' '))) && (!QUOTE)) {
  556.       if (BOLD || INDEX) {
  557.         old = *i;
  558.         ++(*i);
  559.         while ((*i<strlen(str)) && (str[*i]==' ')) 
  560.           ++(*i);
  561.         s = *i;
  562.         while ((*i<strlen(str)) && (str[*i]!=' '))
  563.           ++(*i);
  564.         Copy(w,str,s,*i-s);  /* word name */
  565.         if (UP) {
  566.           strcpy(t,w);
  567.           Upper(t);
  568.           strcpy(w,t);
  569.         }
  570.         strclr(name);
  571.         for(k=0;k<strlen(w);k++){
  572.           switch(w[k]){
  573.              case ' '  : Append(name,"\\ "); break;
  574.              case '_'  : Append(name,"\\_"); break; 
  575.              case '\11': Append(name,"\\ \\ \\ \\ "); break;
  576.              case '\\' : Append(name,"$\\backslash$"); break;
  577.              case '#'  : Append(name,"\\#"); break;
  578.              case '&'  : Append(name,"\\&"); break;
  579.              case '$'  : Append(name,"\\$"); break;
  580.              case '%'  : Append(name,"\\%"); break;
  581.              case '}'  : Append(name,"\\}"); break;
  582.              case '{'  : Append(name,"\\{"); break;
  583.              case '<'  : Append(name,"$<$"); break;
  584.              case '>'  : Append(name,"$>$"); break;
  585.              case '^'  : Append(name,"$\\uparrow$"); break;
  586.              case '~'  : Append(name,"$\\tilde{ }$"); break;
  587.            default:
  588.              AppendCh(name,w[k]);
  589.           }
  590.         }
  591.         addName(name,*c);   /* add to the tree */
  592.         if (BOLD) {
  593.           Append(out,":\\ {\\bf ");
  594.           Append(out,name);
  595.           Append(out,"}\\ ");
  596.         } else {
  597.           Append(out,":");
  598.           *i = old;
  599.         }
  600.       } else
  601.         Append(out,":");
  602.       } else
  603.         Append(out,":");
  604.  } /* HandleFunction */
  605.  
  606. void ProcessString(char *str, char *out, long int *c)
  607. /* process a single string character by character */
  608. {
  609.   char s[MAX];
  610.   int  i;
  611.   
  612.   NOBRACKET = FALSE;
  613.   strcpy(out,"\\leftline{{\\tt ");
  614.  
  615. #ifndef VAX
  616.   sprintf(s,"%5.5li",*c);
  617. #endif
  618.  
  619. #ifdef VAX
  620.   sprintf(s,"%5.5ld",*c);
  621.   for(i=0;i<strlen(s);i++)
  622.     if ( s[i]==' ' )
  623.       s[i]='0';
  624. #endif
  625.  
  626.   Append(out,s);  Append(out,"\\ -\\ ");
  627.   i = 0; QUOTE = FALSE;
  628.   while (i<strlen(str))
  629.    {
  630.      switch(str[i]){
  631.        case ' '  : Append(out,"\\ "); break;
  632.        case '_'  : Append(out,"\\_"); break;
  633.        case '\11': Append(out,"\\ \\ \\ \\ "); break;
  634.        case '\\' : HandleComment(&i,str,out); break;
  635.        case '#'  : Append(out,"\\#"); break;
  636.        case '&'  : Append(out,"\\&"); break;
  637.        case '$'  : Append(out,"\\$"); break;
  638.        case '%'  : Append(out,"\\%"); break;
  639.        case '}'  : Append(out,"\\}"); break;
  640.        case '{'  : Append(out,"\\{"); break;
  641.        case '~'  : Append(out,"$\\tilde{ }$"); break;
  642.        case '^'  : Append(out,"$\\uparrow$"); break;
  643.        case ':'  : HandleFunction(&i,str,out,c); break;
  644.        case '"'  : AppendCh(out,'"');  QUOTE = !QUOTE; break;
  645.      default:
  646.        if (str[i]>' ') {
  647.          if ((!UP) || (QUOTE))
  648.            AppendCh(out,str[i]);
  649.          else
  650.            AppendCh(out,up1(str[i]));
  651.        }
  652.      } /* switch */
  653.      i++;
  654.    } /* while */
  655.   if (!NOBRACKET) {
  656.     Append(out,"}}");
  657.     NOBRACKET = FALSE;
  658.   }
  659. } /* process string */
  660.  
  661.  
  662. void MoreProcessString( char *str, char *out, long int c)
  663. /* handle VARIABLE, and such... */
  664. {
  665.    char ucStr[MAX], s[MAX], name[MAX];
  666.    int  n,i,f,ff;
  667.    
  668.    if (Same(str,0,9,"\\leftline")) {
  669.      Del(str,strlen(str)-2,2);  /* remove }} */
  670.      Append(str,"\\ ");
  671.      strcpy(ucStr,str);
  672.      Upper0(ucStr);
  673.      strclr(out);
  674.      do {
  675.        f = FALSE;
  676.        i = Occurs(str,0,"{\\it$\\backslash");  /* position of any comment */
  677.  
  678.        if ((n=Occurs(ucStr,0," CREATE\\ ")) != last) {
  679.          n += 7;  f = TRUE; }
  680.        else if ((n=Occurs(ucStr,0," VARIABLE\\ ")) != last) {
  681.          n += 9;  f = TRUE; }
  682.        else if ((n=Occurs(ucStr,0," CONSTANT\\ ")) != last) {
  683.          n += 9;  f = TRUE; }
  684.        else if ((n=Occurs(ucStr,0," FVARIABLE\\ ")) != last) {
  685.          n += 10;  f = TRUE; }
  686.        else if ((n=Occurs(ucStr,0," FCONSTANT\\ ")) != last) {
  687.          n += 10;  f = TRUE; }
  688.          
  689.        if (n >= i)  f = FALSE;
  690.        if (f) {
  691.          Copy(s,str,0,n);  Append(out,s);
  692.          /* get name from str */
  693.          Del(str,0,n);  Del(ucStr,0,n);
  694.          do {
  695.            ff = FALSE;
  696.            if (Same(str,0,2,"\\ ")) {
  697.              Del(str,0,2);  Del(ucStr,0,2);
  698.              Append(out,"\\ ");
  699.              ff = TRUE;
  700.            }
  701.          } while( ff );
  702.          n = Occurs(str,0,"\\ ");
  703.          Copy(name,str,0,n);  /* get the name */
  704.          Append(out,"{\\sf ");
  705.          Append(out,name);
  706.          Append(out,"}");
  707.          Del(str,0,n);  Del(ucStr,0,n);
  708.          addName(name,c);  /* add name to list */
  709.        }
  710.      } while( f );
  711.      Append(out,str);
  712.      Del(out,strlen(out)-2,2);
  713.      Append(out,"}}");
  714.    } else {
  715.       strcpy(out,str);
  716.    }
  717. } /* MoreProcessString */
  718.  
  719. /* Globals for OutputIndex */
  720.  
  721. int lineCount,i;      /* number of lines, number of items on a line */
  722. char outt[MAX];       /* line to output */
  723.  
  724. void Display(struct tree *p)
  725. /* display tree data in LaTeX tabular environment */
  726. {
  727.    char t[MAX],w[MAX];
  728.    int  j;
  729.    
  730.    Append(outt,"{\\rm ");  Append(outt,p->name);  Append(outt,"}\\ {\\tt (");
  731.  
  732. #ifndef VAX
  733.   sprintf(w,"%5.5li",p->line);
  734. #endif
  735.  
  736. #ifdef VAX
  737.   sprintf(w,"%5.5ld",p->line);
  738.   for(j=0;j<strlen(w);j++)
  739.     if ( w[j]==' ' )
  740.       w[j]='0';
  741. #endif
  742.  
  743.    Append(outt,w);
  744.    if (i<2) {
  745.      Append(outt,")} & ");
  746.      i++;
  747.    } else {
  748.      i=0;
  749.      Append(outt,")} \\\\");
  750.      WriteTheString(g,outt);
  751.      strclr(outt);  lineCount++;
  752.      if (lineCount>35) {
  753.        WriteTheString(g,"\\end{tabular}");
  754.        WriteTheString(g,"\\clearpage");
  755.        WriteTheString(g,"\\begin{tabular}{lllll}");
  756.        lineCount = 0;
  757.      }
  758.    }
  759. } /* display */
  760.  
  761. void WalkTree(struct tree *p)
  762. /* Inorder traversal of name tree */
  763. {
  764.    if (p != NULL) {
  765.      WalkTree(p->left);
  766.      Display(p); 
  767.      WalkTree(p->right);
  768.    }
  769. } /* WalkTree */
  770.  
  771. void OutputIndex(void)
  772. /* print the index of names */
  773. {
  774.    int q;
  775.    
  776.    strclr(outt);  i = 0;  lineCount = 0;
  777.    if ( (!RA) || ((RA) && (!TOC)) ) {  /* article */
  778.      WriteTheString(g,"\\clearpage");
  779.      if (SECTIONS)
  780.        WriteTheString(g,"\\section{Index} \\vspace{0.5in}");
  781.      else
  782.        WriteTheString(g,"\\begin{center} {\\huge Index} \\end{center} \\vspace{0.5in}");
  783.      WriteTheString(g,"\\vspace{0.5in}");
  784.      WriteTheString(g,"\\hfil \\break");
  785.    } else {                            /* report */
  786.      WriteTheString(g,"\\appendix");
  787.      WriteTheString(g,"\\chapter{Index of User-Defined Names}");
  788.    }
  789.    WriteTheString(g,"\\begin{tabular}{lllll}");
  790.    WalkTree(root);
  791.    if (i != 0) {
  792.      for(q=1;q<=3-(i+1);q++)
  793.        Append(outt," & ");
  794.      Append(outt," \\\\");
  795.      WriteTheString(g,outt);
  796.    }
  797.    WriteTheString(g,"\\end{tabular}");
  798. } /* outputIndex */
  799.  
  800. void Convert(char *infile, long int *count)
  801. /* do the conversion */
  802. {
  803.    char str[MAX],out[MAX],date[MAX],time[MAX];
  804.    int  done,n;
  805.    
  806.    if (FIRST) {
  807.      CopyHeader();
  808.      GetProgramInfo();
  809.      if (TOC)
  810.        WriteTheString(g,"\\tableofcontents \\clearpage");
  811.      WriteTheString(g,"\\pagestyle{plain}");
  812.      WriteTheString(g,"\\pagenumbering{arabic}");
  813.      WriteTheString(g,"\\setcounter{page}{1}");
  814.      WriteTheString(g,"\\small");
  815.      fclose(f);
  816.      FIRST = FALSE;
  817.      f = fopen(infile,"r");
  818.      *count = 0;
  819.    }
  820.    done = FALSE;
  821.    done = ReadTheString(f,str);
  822.    strclr(out);
  823.    while (!done) {
  824.      if ( ((n=Occurs(str,0,"\\ Section:")) != last) && (TOC) ) {
  825.        Del(str,0,n+10);
  826.        strcpy(out,"\\section{"); Append(out,str);  Append(out,"}");
  827.        SECTIONS = TRUE; }
  828.      else if ( ((n=Occurs(str,0,"\\ Subsection:")) != last) && (TOC) ) {
  829.        Del(str,0,n+13);
  830.        strcpy(out,"\\subsection{"); Append(out,str);  Append(out,"}");
  831.        SECTIONS = TRUE; }
  832.      else if ( ((n=Occurs(str,0,"\\ Subsubection:")) != last) && (TOC) ) {
  833.        Del(str,0,n+16);
  834.        strcpy(out,"\\subsubsection{"); Append(out,str);  Append(out,"}");
  835.        SECTIONS = TRUE; }
  836.      else if (Same(str,0,8,"\\ latex:")) {
  837.        Del(str,0,8);  WriteTheString(g,str); }  /* \ latex: form */
  838.      else if ( (RA) && (TOC) && ((n=Occurs(str,0,"\\ Chapter:"))!=last) ) {
  839.        Del(str,0,n+10);
  840.        strcpy(out,"\\chapter{"); Append(out,str);  Append(out,"}"); }
  841.      else {
  842.        ProcessString(str,out,count);
  843.        strcpy(str,out);
  844.        MoreProcessString(str,out,*count);
  845.        (*count)++;
  846.      }
  847.      WriteTheString(g,out);
  848.      out[0]='\0'; str[0]='\0';
  849.      done = ReadTheString(f,str);
  850.    } /* while */
  851. } /* convert */
  852.  
  853. void KillTree(struct tree *p)
  854. /* kill the old tree */
  855. {
  856.    if (p != NULL) {
  857.      KillTree(p->left);
  858.      KillTree(p->right);
  859.      Dispose(p);
  860.    }
  861. } /* KillTree */
  862.  
  863. void UpdateCount(char *c, char *outfile)
  864. /* Kludge to update the count when using multiple files */
  865. {
  866.    int done;
  867.    char str[MAX],*t;
  868.    
  869.    done = FALSE;
  870.    f = fopen(outfile,"r");
  871.    t = "dpp6113909294.tmp";
  872.    g = fopen(t,"w");
  873.    done = ReadTheString(f,str);
  874.    while (!done) {
  875.      if (Occurs(str,0,"{\\bf Lines:}") != last) {
  876.        strcpy(str,"{\\bf Lines:}\\ \\ "); Append(str,c);
  877.        Append(str," \\hfil \\break \\clearpage");
  878.      }
  879.      WriteTheString(g,str);
  880.      done = ReadTheString(f,str);
  881.    }
  882.    fclose(f);
  883.    fclose(g);
  884.    f = fopen(t,"r");
  885.    g = fopen(outfile,"w");
  886.    done = FALSE;
  887.    done = ReadTheString(f,str);
  888.    while (!done) {
  889.      WriteTheString(g,str);
  890.      done = ReadTheString(f,str);
  891.    }
  892.    fclose(f);  fclose(g);
  893.    remove(t);
  894. }
  895.  
  896. void CommandFile(char *cmdfile)
  897. /* process a .f2l command file */
  898. {
  899.    int  done,skip,b,n,i;
  900.    char str[MAX],outfile[MAX],infile[MAX],t[MAX];
  901.    long int c;
  902.    
  903.    printf("Command file: %s\n\n",cmdfile);
  904.    w = fopen(cmdfile,"r");
  905.    done = FALSE;
  906.    strcpy(outfile,"a.tex");
  907.    done = ReadTheString(w,str);
  908.    while (!done) {
  909.      if ((n=Occurs(str,0,"# Output: "))!=last) {
  910.        Del(str,0,n+10);
  911.        done = TRUE;
  912.        strcpy(outfile,str);
  913.      }
  914.      done = ReadTheString(w,str);
  915.    }
  916.    fclose(w);
  917.    g = fopen(outfile,"w");
  918.    printf("Output file : %s\n\nProcessing file...\n\n",outfile);
  919.    w = fopen(cmdfile,"r");
  920.    c = 0;
  921.    done = FALSE;  FIRST = TRUE;
  922.    done = ReadTheString(w,str);
  923.    while (!done) {
  924.      skip = FALSE;  
  925.      infile[0]='\0';
  926.      if ( str[0]!='\0' ) {
  927.        n = 0;
  928.        while( (str[n]==' ') || (str[n]=='\11') )
  929.          n++;
  930.        for(i=n;i<strlen(str);i++)
  931.          if ( (str[i]!='#') && (!skip) && (str[i]!=' ') )
  932.            AppendCh(infile,str[i]);
  933.          else
  934.            skip = TRUE;
  935.      }
  936.      if (!Equal(infile,"")) {  /* process this file */
  937.        f = fopen(infile,"r");
  938.        printf("      %s\n",infile);
  939.        Convert(infile,&c);
  940.        fclose(f);
  941.      }
  942.      done = ReadTheString(w,str);
  943.    }
  944.    if (INDEX)  OutputIndex();
  945.    WriteTheString(g,"\\end{document}");
  946.    fclose(g);  fclose(w);
  947.    sprintf(t,"%ld",c-1);
  948.    UpdateCount(t,outfile);
  949.    printf("\n\n%s lines total.\n\n",t);
  950. } /* CommandFile */
  951.  
  952. void ConvertFile(char *infile)
  953. /* handle the source and dest files and convert */
  954. {
  955.    char t[MAX],outfile[MAX];  long int c;
  956.    
  957.    if ( (Occurs(infile,0,".f2l")!=last) || (Occurs(infile,0,".F2L")!=last) )
  958.      CommandFile(infile);
  959.    else {
  960.      StripSuffix(infile,outfile);
  961.      Append(outfile,".tex");
  962.      printf("\nStarting conversion...\n\n");
  963.      g = fopen(outfile,"w");
  964.      FIRST = TRUE;
  965.      f = fopen(infile,"r");
  966.      Convert(infile,&c);
  967.      if (INDEX)
  968.        OutputIndex();
  969.      fclose(f);
  970.      WriteTheString(g,"\\end{document}");
  971.      fclose(g);
  972.      printf("Conversion complete, %ld lines.\n\n",c);
  973.    }
  974.    KillTree(root);
  975.    root = NULL;
  976. } /* ConvertFile */
  977.  
  978.